package com.mxpio.erp.plm.monitoring;

import com.mxpio.erp.common.plm.entity.*;
import com.mxpio.erp.common.plm.service.*;
import com.mxpioframework.camunda.service.BpmnFlowService;
import com.mxpioframework.camunda.vo.AllTaskRetVO;
import com.mxpioframework.camunda.vo.TaskVO;
import com.mxpioframework.common.vo.Result;
import com.mxpioframework.jpa.JpaUtil;
import com.mxpioframework.jpa.query.Criteria;
import com.mxpioframework.message.service.MessageService;
import com.mxpioframework.security.util.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import org.camunda.bpm.engine.history.HistoricProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 审批阶段的站内信
 */
@Slf4j
@Component
public class ProjectApprovalMessage implements JavaDelegate {

    public static final String[] channelCodes = {"innerMsg"};

    @Autowired
    private BpmnFlowService bpmnFlowService;
    @Resource
    private MessageService messageService;//消息
    @Autowired
    private ProjectInfoService projectInfoService;
    @Autowired
    private ProjectTaskService projectTaskService;
    @Autowired
    private ProjectInfoApprovalService projectInfoApprovalService;
    @Autowired
    private ProjectInfoChangeService projectInfoChangeService;
    @Autowired
    private ProjectInfoCompleteService projectInfoCompleteService;
    @Autowired
    private ProjectInfoEndService projectInfoEndService;
    @Autowired
    private ProjectTaskExecutionLogService projectTaskExecutionLogService;
    @Autowired
    private ProjectPauseOperationService projectPauseOperationService;
    @Autowired
    private ProjectRecoveryOperationService projectRecoveryOperationService;





    @Override
    @Transactional
    public void execute(DelegateExecution delegateExecution) throws Exception {
        String processInstanceId = delegateExecution.getProcessInstanceId();
        //判断是哪个审批流程
        //立项
        ProjectInfoApproval approval = JpaUtil.linq(ProjectInfoApproval.class).equal("processInstanceId", processInstanceId).findOne();
        //变更
        ProjectInfoChange change = JpaUtil.linq(ProjectInfoChange.class).equal("processInstanceId", processInstanceId).findOne();
        //结项
        ProjectInfoComplete complete = JpaUtil.linq(ProjectInfoComplete.class).equal("processInstanceId", processInstanceId).findOne();
        //终止
        ProjectInfoEnd end = JpaUtil.linq(ProjectInfoEnd.class).equal("processInstanceId", processInstanceId).findOne();
        //任务完工
        ProjectTaskExecutionLog taskExecutionLog = JpaUtil.linq(ProjectTaskExecutionLog.class).equal("processInstanceId", processInstanceId).findOne();
        //项目暂停
        ProjectPauseOperation pauseOperation = JpaUtil.linq(ProjectPauseOperation.class).equal("processInstanceId", processInstanceId).findOne();
        //项目恢复
        ProjectRecoveryOperation recoveryOperation = JpaUtil.linq(ProjectRecoveryOperation.class).equal("processInstanceId", processInstanceId).findOne();


        Integer pageSize=100000;
        Integer pageNo=1;
        Criteria criteria = new Criteria();
        TaskVO taskVO = getTitle(processInstanceId,criteria,pageSize,pageNo);
        //判断是哪个审批流程
        if (approval != null){
            String[] toUsers = {approval.getApplicant()};
            //发送站内信
            messageService.sendMessage(channelCodes,SecurityUtils.getLoginUsername(),toUsers,taskVO.getTitle(),"您的申请已完成审批，请查看最终审批结果。");
        }else if (change != null){
            String[] toUsers = {change.getApplicant()};
            //发送站内信
            messageService.sendMessage(channelCodes,SecurityUtils.getLoginUsername(),toUsers,taskVO.getTitle(),"您的申请已完成审批，请查看最终审批结果。");

        } else if (complete != null){
            String[] toUsers = {complete.getApplicant()};
            //发送站内信
            messageService.sendMessage(channelCodes,SecurityUtils.getLoginUsername(),toUsers,taskVO.getTitle(),"您的申请已完成审批，请查看最终审批结果。");

        } else if (end != null){
            String[] toUsers = {end.getApplicant()};
            //发送站内信
            messageService.sendMessage(channelCodes,SecurityUtils.getLoginUsername(),toUsers,taskVO.getTitle(),"您的申请已完成审批，请查看最终审批结果。");

        }else if (taskExecutionLog != null) {
            String[] toUsers = {taskExecutionLog.getApplicant()};
            //发送站内信
            messageService.sendMessage(channelCodes,SecurityUtils.getLoginUsername(),toUsers,taskVO.getTitle(),"您的申请已完成审批，请查看最终审批结果。");
        } else if (pauseOperation !=null) {
            String[] toUsers = {pauseOperation.getApplyUser()};
            //发送站内信
            messageService.sendMessage(channelCodes,SecurityUtils.getLoginUsername(),toUsers,taskVO.getTitle(),"您的申请已完成审批，请查看最终审批结果。");
        } else if (recoveryOperation !=null) {
            String[] toUsers = {recoveryOperation.getApplyUser()};
            //发送站内信
            messageService.sendMessage(channelCodes,SecurityUtils.getLoginUsername(),toUsers,taskVO.getTitle(),"您的申请已完成审批，请查看最终审批结果。");
        }
    }

    /**
     * 查找流程的标题
     * @param criteria
     * @param pageSize
     * @param pageNo
     */
    public TaskVO getTitle(String processInstanceId,Criteria criteria,Integer pageSize,Integer pageNo){
    Set<String> authorities = SecurityUtils.getAuthorityKeys();
    String username = SecurityUtils.getLoginUsername();
        Pageable pageAble = PageRequest.of(pageNo-1, pageSize);
    AllTaskRetVO allTaskRetVO = bpmnFlowService.getAllTasks(username,authorities, criteria, pageAble);
    List<TaskVO> taskVOList = allTaskRetVO.getAllTasks();
    long total = allTaskRetVO.getCount();

//    Pageable pageAble = PageRequest.of(pageNo-1, pageSize);
        if(CollectionUtils.isNotEmpty(taskVOList)){
        int startIndex = (pageNo-1)*pageSize;
        if(startIndex< taskVOList.size()){
            List<TaskVO> returnList = taskVOList.subList(startIndex, Math.min(startIndex + pageSize, taskVOList.size()));
            for(TaskVO task:returnList){
                if (task.getProcessInstanceId().equals(processInstanceId)){
                HistoricProcessInstance historicProcessInstance = bpmnFlowService.getHistoricProcessInstanceById(task.getProcessInstanceId());
                String formKey = bpmnFlowService.getTaskFormKey(task.getProcessDefinitionId(), task.getTaskDefinitionKey());
                task.setTitle(bpmnFlowService.getTitleByInstanceId(historicProcessInstance.getId()));
                task.setHasForm(StringUtils.isNotEmpty(formKey));
                return task;
            }
            }
        }
    }
        return null;
}
}
